/* 
    pop()
        -该方法可以删除并返回数组的最后一个元素
*/
/* 
    unshift()
    - 向数组的开头添加一个或者多个元素，并且返回数组的长度
    - 向前面加入元素之后，其他元素的索引会依次调整
*/


// 创造按键编码表
const keyMap=new Map([[38,'up'],[40,'down'],[37,'left'],[39,'right']]);
const againstMap=new Map([['up','down'],['down','up'],['left','right'],['right','left']]);
console.log(keyMap);

// 获取外层容器
var $border=$('body #border');
$border.css('position','relative');
// 获取开始按钮
var $start=$('#border #start');


/* 函数集合STRAT */
// 创造一个方块
var createBox=()=>{
    // 创造元素
    let $box=$('<div></div>');
    // 添加样式
    $box.css({
        width: '15',
        height: '15',
        backgroundColor:'#008c8c',
        position: 'absolute',
    })
    // 添加到容器
    $box.appendTo($border) ;
    return $box;
}

// 创造身体并且初始化
var createItem=()=>{
    const $item=createBox();
    body.push($item);
    // 设置初始位置
    position($item);

    // 计算元素的初始位置
    function position($item){
        // 如果不存在蛇尾，刚刚创建的元素就设置为蛇尾
        if($tail==null){
            $item.css({
                top:'300px',
                left:'300px'
                // top和left要加单位
                // css里面不能进行计算
            });
            // 设置初始位置
            $item.locationX=20;
            $item.locationY=20;
            $item.direction='up';
            // 记录在身体中的位置
            $item.index=1;
        }else{
            $item.direction=$tail.direction;
            $item.index=$tail.index+1;
            if($tail.direction=='right'){
                $item.locationX=$tail.locationX-1;
                $item.locationY=$tail.locationY;
            }else if($tail.direction=='left'){
                $item.locationX=$tail.locationX+1;
                $item.locationY=$tail.locationY;
            }else if($tail.direction=='up'){
                $item.locationX=$tail.locationX;
                $item.locationY=$tail.locationY+1;
            }else{
                $item.locationX=$tail.locationX;
                $item.locationY=$tail.locationY-1;
            }
            show(body);
        }
        $tail=$item;
    }

    // 返回身体元素
    return $item;
}

// 创造食物
var createFood=()=>{
    let foodX=Math.round(Math.random()*39)+1;
    let foodY=Math.round(Math.random()*39)+1;
    while(isOverLap(foodX,foodY)){
        foodX=Math.round(Math.random()*39)+1;
        foodY=Math.round(Math.random()*39)+1;
    }
    $food=createBox();
    $food.locationX=foodX;
    $food.locationY=foodY;
    show([$food]);
}

// 判断是否重叠
var isOverLap=(locationX,locationY)=>{
    for(let item of body){
        if(item.locationX==locationX&&item.locationY==locationY)
            return true;
    }
    return false;
}

// 设置全体的一次移动
var move=()=>{
    // 判断是否修改方向
    for(let $itemB of body){
        for(let itemT of turn){
            if($itemB.locationX==itemT.locationX&&$itemB.locationY==itemT.locationY){
                $itemB.direction=itemT.direction;
                if($itemB==$tail)
                    turn.pop();
            }
        }
    }

    // 遍历身体数组
    for(let $item of body){
        let direction=$item.direction;
        if(direction=='right'){
            $item.locationX++;
        }else if(direction=='left'){
            $item.locationX--;
        }else if(direction=='up'){
            $item.locationY--;
        }else if(direction=='down'){
            $item.locationY++;
        }
    }

    // 判断是否吃到食物
    if(isOverLap($food.locationX,$food.locationY)){
        $food.remove();
        createFood();
        createItem();
    }

    // 修改位置
    show(body);
    // 判断是否游戏结束
    if(lose()){
        var res=confirm("此次游戏失败，要重新开始吗？");
        res&&reset();
        res||clearInterval(tag);
    }
    // console.log(body);

}


// 修改元素现在的位置
var show=(arr)=>{
    for(let $item of arr){
        let positionX=($item.locationX-1)*15+'px';
        let positionY=($item.locationY-1)*15+'px';
        $item.css({
            top:positionY,
            left:positionX
        })
    }
}


// 判断游戏是否结束
var lose=()=>{
    // 判断是否撞墙
    function toWall(){
        if($head.locationX==41||$head.locationX==0||$head.locationY==41||$head.locationY==0)
            return true;
        else return false;
    }

    // 判断是否咬到自己
    function eatSelf(){
        for(let item of body){
            if(item!=$head){
                if(item.locationX==$head.locationX&&item.locationY==$head.locationY){
                    return true;
                }
            }
        }
        return false;
    }

    return toWall()||eatSelf();
}

// 重新开始
var reset=()=>{
    for(let $item of body){
        $item.remove();
        $item=null;
    }
    if($food) {
        $food.remove();
        $food=null;
    }
    turn=null;
    clearInterval(tag);
    play();
}


// 开始游戏
var play=()=>{
    // 环境初始化
    // 初始蛇尾蛇头
    $tail=null;
    $head=null;
    // 初始食物
    $food=undefined;
    // 创造一个身体集合
    body=[];
    // 创造一个定时器标识
    tag=null;
    // 创造一个转折点集合
    turn=[];

    // 首先创造🐍头 
    // 蛇尾在函数中自动交换 
    // 创造的身体元素自动加入body
    $head=createItem($tail);
    let $item=createItem($tail);
    // 创造一个食物 在函数中为food赋值
    createFood();

    // console.log(body);

    // 🐍的自动移动
    tag=setInterval(function() {
        move();
    },400)


    // 监听方向的改变
    // 监听速度增加
    $(document).keydown(function(e) {
        e.preventDefault();

        // R重开
        if(e.keyCode==82){
            reset();
        }

        // shift加速
        if(e.keyCode==16){
            clearInterval(tag);
            tag=setInterval(function() {
                move();
            },200)
        }
        let direction=keyMap.get(e.keyCode);
        if(direction){
            // 遍历循环，判断同一位置是否施加两个指令
            let tag=null;

            // 判断与前进相反的方向
            if(againstMap.get(direction)==$head.direction) tag=true;
            // 判断短时间内的多个方向
            for(let item of turn){
                if(item.locationX==$head.locationX&&item.locationY==$head.locationY){
                    item.direction=direction;
                    tag=true;
                }
            }
            if(!tag){
                // 往待执行指令列表中添加数据
                turn.unshift({
                    direction,
                    locationY:$head.locationY,
                    locationX:$head.locationX
                })
            }
        }

        // 监听速度的还原
        $(document).keyup(function(e){
            if(e.keyCode==16){
                clearInterval(tag);
                tag=setInterval(function() {
                    move();
                },400)
            }
        });

    })
}
/* 函数集合END */

// 点击开始游戏
$start.click(function(){
    $(this).css('display', 'none');
    play();
})








